#ifndef _STI_VIEW_
#define _STI_VIEW_

#include "stdafx.h"
#include <wtypes.h>

#define MAX_INFO_LEN 128

struct TPicPar   //Image parameters
{
  int Type;        //Type.
  int NumPages;    //Number of pages in the image
  int Depth;       //Color depth (bit).
  int Transparent; //Transparency presence.
  int Red;         //Color components which is considered to be transparent.
  int Green;
  int Blue;
};

struct TPagePar    //Structure of image page.
{
  int Width;         //Width and height of page
  int Height;
  int DispX;         //Pages delta. Often used
  int DispY;         //if pages are animation frames
  int Red;           //Color components which is considered to be transparent.
  int Green;         //Are used only in page insertion to the image
  int Blue;
};

typedef BYTE TColor[3]; 
#define HEADER ((StiHeader *)Data)
#define PALETTE ((TColor *)(HEADER+1))
#define FAT ((StiRecord *)(PALETTE+256))
#define PAGES ((BYTE *)(FAT+HEADER->Count))
#define PAGE ((WORD *)(HEADER+1))

struct StiHeader
{
  char Ident[4];   // line "STCI"
  int Size0;       // there is either unpacked picture size, or == SizePack
                   // or some shit - very big but round number
  int SizePack;    // total size of packed images
  char Reserv0[4];
  char Type;       // type STI 0x04 - singlepage
                   //         0x28,0x29 - multipage
  char Reserv1[3];
  short int Height;
  short int Width;
  short int ColorCount; // somebody guessed, that there is the number of colors
  char Reserv2[2];
  short int Count;
  char Reserv3[34];
};
struct StiRecord
{
  int Disp;
  int Len;
  short int DispX;
  short int DispY;
  short int Height;
  short int Width;
};

class CSTIviewer
{
public:
  enum
  {
    E_OK              =  0,
    E_ERROR           =  1,
    E_CANT_OPEN_FILE  =  2,
    E_NO_PICTURE      =  3,
    E_NO_PAGE         =  4,
    E_NO_FILENAME     =  5,
    E_BAD_FILE        =  6,
    E_CANT_READ_FILE  =  7,
    E_BAD_FORMAT      =  8,
    E_NUM_ERRORS,
  };

  CSTIviewer();
  ~CSTIviewer();

  int openFile( const char * chFileName );
  int openPage( int nNumber );

  int getNumPages( int & nPages ) const;
  int getPageRes( int & nWidth, int & nHeight ) const;
  int getColorDepth( int & nDepth ) const;

  PBYTE             getPalettePtr() const;
  PBYTE             getImagePtr()   const;
  PBITMAPINFO       getBMPINFOptr() const;
  PBITMAPFILEHEADER getBMPFHptr()   const;
  BYTE              getPixelColor( int x, int y ) const;
  
  bool  canPaint();
  const char * getErrName( int err ) const;
  void  closeImage();
protected:
private:
  enum
  {
    enPictureOk = 1,
    enPageOk    = 2,    
  };
  int isPicture( BYTE *Data ) const;
  int openPicture(BYTE *Data, int DataSize, struct TPicPar *Par);
  int getLine(BYTE *Line, int Width);
  int getPalette( PALETTEENTRY *Pal );
  int openPage(int Page, struct TPagePar *Par);
  int getLine16(unsigned short *Line, int Width);
  int getLine8(BYTE *Line, int Width);
  void swapLines( BYTE *Line, int height, int width );

  TPicPar   m_tpicPictureParameters;
  TPagePar  m_tpagPageParameters;

  BYTE      * m_pbFileData;
  BYTE      * m_pbWholeBMPData;
  BYTE      * m_pbBMPPaletteData;
  BYTE      * m_pbBMPImageData;
  WORD      * m_pwPageData;
  StiHeader * m_pHeader;
  TColor    * m_pPalette;
  StiRecord * m_pFat;
  StiRecord * m_pRecord;
  WORD      * m_pwPosition;
  WORD      * m_pwPage;
  BYTE      * m_pbPos;
  BYTE      * m_pbData;
  BYTE      * m_pbPages;
  char      * m_pchErrNames[E_NUM_ERRORS];
  int         m_nDataSize;
  int         m_nLastPage;
  int         m_nAlignedWidth;
  BYTE        m_bFlags;
};

#endif